from abc import ABC, abstractmethod


'''
抽象方法

下面的代码中，我们定义了一个抽象基类 Shape，它包含了两个抽象方法 area 和 perimeter。这两个方法在基类中并没有实现，而是让派生类去实现。
接下来，我们定义了两个派生类 Square 和 Circle，它们都继承自基类 Shape，并且分别实现了基类中定义的抽象方法 area 和 perimeter。
由于这两个方法是抽象方法，所以必须在每个非抽象的子类中实现它们，否则将会导致类型错误。（这是加@abstractmethod的意义，必须去实现）

使用抽象方法可以使得代码更加规范和模块化，从而让程序更易于扩展和维护。如果某个类需要满足一定的特定接口，
但是具体实现可以有多种方式，那么就可以考虑使用抽象方法来定义这个接口。
'''


class Shape(ABC):

    @abstractmethod  # 抽象方法需要标注上这个装饰器
    def area(self):
        pass

    @abstractmethod
    def perimeter(self):
        pass


class Square(Shape):

    def __init__(self, side):
        self.side = side

    def area(self):
        return self.side ** 2

    def perimeter(self):
        return 4 * self.side


class Circle(Shape):

    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return 3.14 * self.radius ** 2

    def perimeter(self):
        return 2 * 3.14 * self.radius
